/*
 * Copyright (c) 2006-2020, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2020-12-16     sj-wd       the first version
 */
#include "board.h"
#include "drv_common.h"
#include <rtthread.h>
#include <rtdevice.h>
#include <stm32h7xx.h>
#include "page_ui.h"

#define DOUT_SET        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET)
#define DOUT_RET        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET)
#define DCLK_SET        HAL_GPIO_WritePin(GPIOH,GPIO_PIN_3,GPIO_PIN_SET)
#define DCLK_RET        HAL_GPIO_WritePin(GPIOH,GPIO_PIN_3,GPIO_PIN_RESET)
#define DIN             HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_2)
#define delay_us(x)     HAL_Delay(x)

#define TP_PRES_DOWN 0x80
#define TP_CATH_PRES 0x40

uint8_t CMD_RDX=0XD0;
uint8_t CMD_RDY=0X90;



_m_tp_dev tp_dev=
{
    0,
    0,
    0,
    0,
    0,
    0.0644122362,
    -0.0893141925,
    -13,
    349,
    0,
};

void rt_touch_io_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOH_CLK_ENABLE();

    GPIO_InitStruct.Pin = GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
}

void TP_Write_Byte(uint8_t num)    {
    uint8_t count=0;
    for(count=0;count<8;count++)
    {
        if(num&0x80)DOUT_SET;
        else DOUT_RET;
        num<<=1;
        DCLK_RET;
        DCLK_SET;
    }
}

uint16_t TP_Read_AD(uint8_t CMD){
    uint8_t count=0;
    uint16_t Num=0;
    DCLK_RET;
    DOUT_RET;
    TP_Write_Byte(CMD);
    delay_us(6);
    DCLK_RET;
    delay_us(1);
    DCLK_SET;
    DCLK_RET;
    for(count=0;count<16;count++)
    {
        Num<<=1;
        DCLK_RET;
        DCLK_SET;
        if(DIN)Num++;
    }
    Num>>=4;
    return(Num);
}

#define READ_TIMES 5
#define LOST_VAL 1

uint16_t TP_Read_XOY(uint8_t xy){
    uint16_t i, j;
    uint16_t buf[READ_TIMES];
    uint16_t sum=0;
    uint16_t temp;
    for(i=0;i<READ_TIMES;i++)buf[i]=TP_Read_AD(xy);
    for(i=0;i<READ_TIMES-1; i++)
    {
        for(j=i+1;j<READ_TIMES;j++)
        {
            if(buf[i]>buf[j])
            {
                temp=buf[i];
                buf[i]=buf[j];
                buf[j]=temp;
            }
        }
    }
    sum=0;
    for(i=LOST_VAL;i<READ_TIMES-LOST_VAL;i++)sum+=buf[i];
    temp=sum/(READ_TIMES-2*LOST_VAL);
    return temp;
}

uint8_t TP_Read_XY(uint16_t *x,uint16_t *y){
    uint16_t xtemp,ytemp;
    xtemp=TP_Read_XOY(CMD_RDX);
    ytemp=TP_Read_XOY(CMD_RDY);
    *x=xtemp;
    *y=ytemp;
    return 1;
}

#define ERR_RANGE 50
uint8_t TP_Read_XY2(uint16_t *x,uint16_t *y) {
    uint16_t x1,y1;
    uint16_t x2,y2;
    uint8_t flag;
    flag=TP_Read_XY(&x1,&y1);
    if(flag==0)return(0);
    flag=TP_Read_XY(&x2,&y2);
    if(flag==0)return(0);
    if(((x2<=x1&&x1<x2+ERR_RANGE)||(x1<=x2&&x2<x1+ERR_RANGE))
    &&((y2<=y1&&y1<y2+ERR_RANGE)||(y1<=y2&&y2<y1+ERR_RANGE)))
    {
        *x=(x1+x2)/2;
        *y=(y1+y2)/2;
        return 1;
    }else return 0;
}

uint8_t TP_Scan(uint8_t tp){
    if(TP_Read_XY2(&tp_dev.x,&tp_dev.y)){
        tp_dev.x=tp_dev.xfac*tp_dev.x+tp_dev.xoff;
        tp_dev.y=tp_dev.yfac*tp_dev.y+tp_dev.yoff;
    }
    if(tp_dev.x!=0&&tp_dev.y!=0) return 0;
        else return 1;
}
